using GamFi.API.Application.Exceptions;
using GamFi.API.Application.Interfaces;
using GamFi.API.Application.Resources;
using MediatR;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Localization;

namespace GamFi.API.Application.Features.Queries.Image.DeleteImage;

public class DeleteImageCommandHandler(
    IDbContext dbContext,
    IS3Service s3Service,
    IUserContext userContext,
    IStringLocalizer<ExceptionMessages> localizer)
    : IRequestHandler<DeleteImageCommand>
{
    /// <inheritdoc/>
    public async Task Handle(DeleteImageCommand request, CancellationToken cancellationToken)
    {
        if (request is null)
            throw new RequestException(localizer[nameof(RequestException.RequestIsEmpty)]);

        var currentUserId = userContext.CurrentUserId;

        if (currentUserId is null)
            throw new UserException(localizer[nameof(UserException.PermissionDenied)]);

        var userInfoWithImage = await dbContext.UserInfos
            .Include(u => u.Image)
            .Where(u => u.UserId == currentUserId)
            .FirstOrDefaultAsync(i => i.ImageId == Guid.Parse(request.ImageId), cancellationToken);

        if (userInfoWithImage is null)
            throw new UserException(localizer[nameof(UserException.UserByIdNotFound)]);

        if (userInfoWithImage.Image is null)
            throw new ImageException(localizer[nameof(ImageException.ImageByIdNotFound)]);

        if (userInfoWithImage.Image.CreatedBy != currentUserId)
            throw new UserException(localizer[nameof(UserException.PermissionDenied)]);

        await s3Service.DeleteAsync(userInfoWithImage.Image.Address, cancellationToken: cancellationToken);
        dbContext.Images.Remove(userInfoWithImage.Image);
        await dbContext.SaveChangesAsync(cancellationToken);
    }
}